/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hxg.portmgr.core.oper.snmp.task;

import hxg.portmgr.core.device.intf.AbstractIntf;
import hxg.portmgr.core.oper.snmp.SnmpOper;
import hxg.portmgr.core.oper.snmp.SnmpOperUtils;
import hxg.portmgr.core.oper.snmp.oidgroup.OidEntry;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.snmp4j.CommunityTarget;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.Variable;

/**
 *
 * @author hxg
 */
public class TaskManager {

    public static List<TaskSupport> getCollectableResult(SnmpOper oper) {
        List<TaskSupport> list = new ArrayList<>();
        Method[] methods = oper.getClass().getMethods();
        for (Method m : methods) {
            TaskSupport support = m.getAnnotation(TaskSupport.class);
            if (support != null) {
                list.add(support);
            }
        }
        return list;
    }

    private static Method getMethod(SnmpOper oper, String taskSupportname) {
        Method[] methods = oper.getClass().getMethods();
        for (Method m : methods) {
            TaskSupport support = m.getAnnotation(TaskSupport.class);
            if (support != null) {
                if (taskSupportname.equals(support.chsname())) {
                    return m;
                }
            }
        }
        return null;
    }

    public static List<TaskResultCell> getResult(SnmpOper oper, String taskSupportName, TaskGetMode getMode, List<? extends AbstractIntf> intflist) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
        List<TaskResultCell> list = new ArrayList<>();
        Method m = getMethod(oper, taskSupportName);
        OidEntry[] oidGroups = (OidEntry[]) m.invoke(oper);
        CommunityTarget target = SnmpOperUtils.getTarget(oper.getIp(), oper.getReadCommunity());
        switch (getMode) {
            case Row:
                for (AbstractIntf inf : intflist) {
                    Map<OidEntry, Variable> mp = SnmpOperUtils.getIntfVariblesOfIntf(inf.getIndex(), oidGroups, target);
                    long date = System.currentTimeMillis();
                    for (OidEntry entry : mp.keySet()) {
                        TaskResultCell taskEntry = new TaskResultCell();
                        taskEntry.setScandate(date);
                        taskEntry.setIfidx(inf.getIndex());
                        taskEntry.setIp(oper.getIp());
                        taskEntry.setOid(entry.oidValue());
                        taskEntry.setParam(entry.getParamType());
                        taskEntry.setValue(mp.get(entry).toString());
                        list.add(taskEntry);
                    }
                }
                break;
            case Table:
                Map<OID, Map<OidEntry, Variable>> mp = SnmpOperUtils.getVariblesOfOidEntryByRow(oidGroups, target);
                long date = System.currentTimeMillis();
                for (OID oid : mp.keySet()) {
                    Map<OidEntry, Variable> varmp = mp.get(oid);
                    String ifidx = oid.toString();
                    for (OidEntry entry : varmp.keySet()) {
                        TaskResultCell taskEntry = new TaskResultCell();
                        taskEntry.setScandate(date);
                        taskEntry.setIfidx(ifidx);
                        taskEntry.setIp(oper.getIp());
                        taskEntry.setOid(entry.oidValue());
                        taskEntry.setParam(entry.getParamType());
                        taskEntry.setValue(varmp.get(entry).toString());
                        list.add(taskEntry);
                    }
                }
                break;
        }
        return list;
    }

    public static List<TaskResultCell> getResult(String ip, String community, List<OID> oids, List<? extends AbstractIntf> intflist) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
        List<TaskResultCell> list = new ArrayList<>();
        CommunityTarget target = SnmpOperUtils.getTarget(ip, community);
        //Map<OID, List<OID>> oidmp = new HashMap<OID, List<OID>>();
        if (intflist != null && !intflist.isEmpty()) {
            for (AbstractIntf inf : intflist) {
                OID[] sendOids = new OID[oids.size()];
                for (int i = 0; i < oids.size(); i++) {
                    sendOids[i] = ((OID) oids.get(i).clone()).append(inf.getIndex());
                }
                Map<OID, Variable> mp = SnmpOperUtils.getVariablesofOIDs(sendOids, 10, target);
                long date = System.currentTimeMillis();
                for (OID resOid : mp.keySet()) {
                    TaskResultCell taskEntry = new TaskResultCell();
                    taskEntry.setScandate(date);
                    taskEntry.setIfidx(inf.getIndex());
                    taskEntry.setIp(ip);
                    String oidstr = resOid.toString();
                    taskEntry.setOid(oidstr.substring(0, oidstr.lastIndexOf(inf.getIndex())));
                    taskEntry.setParam(null);
                    taskEntry.setValue(mp.get(resOid).toString());
                }
            }
        } else {
            OID[] sendOids = new OID[oids.size()];
            Map<OID, Variable> mp = SnmpOperUtils.getVariablesofOIDs(sendOids, 10, target);
            long date = System.currentTimeMillis();
            for (OID resOid : mp.keySet()) {
                TaskResultCell taskEntry = new TaskResultCell();
                taskEntry.setScandate(date);
                taskEntry.setIfidx("");
                taskEntry.setIp(ip);
                //String oidstr = resOid.toString();
                taskEntry.setOid(resOid.toString());
                taskEntry.setParam(null);
                taskEntry.setValue(mp.get(resOid).toString());
            }
        }
        return list;
    }
}
